package com.budwk.app.sqfw.services.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.sqfw.component.CommonComponent;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.dto.ServiceRecordPdfOrExcelCollDTO;
import com.budwk.app.sqfw.models.Sqfw_cenSusPaper;
import com.budwk.app.sqfw.models.Sqfw_formSummary;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwCompleteflowService;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfwV2.dto.entity.SqfwShopsBaseInfo;
import com.budwk.app.sqfwV2.service.ShopsBaseInfoService;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysLogService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.DateUtils;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.common.result.ResultCode;
import com.budwk.starter.database.service.BaseServiceImpl;
import com.budwk.starter.security.utils.SecurityUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Slf4j
@IocBean(args = {"refer:dao"})
public class SqfwFormsummaryNewServiceImpl extends BaseServiceImpl<Sqfw_formSummary_new> implements SqfwFormsummaryNewService {
    public SqfwFormsummaryNewServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private SqfwCompleteflowService sqfwCompleteflowService;

    @Inject
    private SysLogService sysLogService;
    @Inject
    private ShopsBaseInfoService shopsBaseInfoService;

    @Inject("taskUpdateExecutor")
    private ThreadPoolExecutor taskUpdateExecutor;

    @Inject
    private SysUserService currUserService;

    @Override
    public Result<String> mergePDF(List<ServiceRecordPdfOrExcelCollDTO> conditionList) {
        String pdfUrl = CommonComponent.mergeCompleteflowPDF(conditionList);
        log.info("mergePDF pdfUrl: {}", pdfUrl);
        return Result.data(pdfUrl);
    }

    @Override
    public List<Sqfw_formSummary_new> queryByPlaceAndAddress(String placeName, String address, String type, String unitId) {
        log.info("queryByPlaceAndAddress param placeName: {}, address: {}", placeName, address);
        Criteria cri = Cnd.cri();
        SqlExpressionGroup criSql = cri.where();
        if (StringUtils.isEmpty(unitId)) {
            unitId = SecurityUtil.getUnitId();
        }
        criSql.andEquals(Sqfw_formSummary_new::getType, type)
                .andEquals(Sqfw_formSummary_new::getUnitId, unitId);
        cri.getOrderBy().desc(Sqfw_formSummary_new::getFillDate);
        // 自定义sql
        String sql = "param_data ->>'placeName'='" + placeName + "' and param_data ->>'address'='" + address + "'";
        criSql.and(new Static(sql));
        return query(cri);
    }

    @Override
    public List<Sqfw_formSummary_new> queryBySqfwIdAndType(String sqfwId, String type) {
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup where = cnd.where();
        if (StringUtils.isNotEmpty(sqfwId)) {
            where.andEquals(Sqfw_formSummary_new::getSqfwId, sqfwId);
        }
        where.andEquals(Sqfw_formSummary_new::getType, type);
        cnd.getOrderBy().desc(Sqfw_formSummary_new::getFillDate);
        return this.query(cnd);
    }

    @Override
    public List<Sqfw_formSummary_new> queryBySqfwIdsAndType(List<String> sqfwIds, String type) {
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup where = cnd.where();
        where.andEquals(Sqfw_formSummary_new::getType, type);
        if (sqfwIds.size() > 0) {
            where.andIn(Sqfw_formSummary_new::getSqfwId, sqfwIds.toArray(new String[0]));
        }
        cnd.getOrderBy().desc(Sqfw_formSummary_new::getFillDate);
        return this.query(cnd);
    }

    @Override
    public List<Sqfw_formSummary_new> queryByShopIdsAndType(List<String> shopIds, String type) {
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup where = cnd.where();
        where.andEquals(Sqfw_formSummary_new::getType, type);
        if (shopIds.size() > 0) {
            where.andIn(Sqfw_formSummary_new::getShopsBaseInfoId, shopIds.toArray(new String[0]));
        }
        cnd.getOrderBy().desc(Sqfw_formSummary_new::getFillDate);
        return this.query(cnd);
    }

    @Override
    public List<Sqfw_formSummary_new> queryByLastSummaryId(List<String> lastSummaryIds) {
        Criteria cri = Cnd.cri();
        SqlExpressionGroup criSql = cri.where();
        // 自定义sql
        criSql.and("param_data ->> 'lastSummaryId'", "in", lastSummaryIds);
        return this.query(cri);
    }

    @Override
    public List<Sqfw_formSummary_new> findByPlaceName(String queryValue, String type) {
        List<SqfwShopsBaseInfo> sqfwShopsBaseInfos = shopsBaseInfoService.listByCondition("placeName", queryValue);
        if (sqfwShopsBaseInfos.isEmpty()) {
            return Lists.newArrayList();
        }
        // 取出所有的id
        List<String> shopsIds = sqfwShopsBaseInfos.stream().map(SqfwShopsBaseInfo::getId).collect(Collectors.toList());
        List<Sqfw_formSummary_new> list = this.queryByShopIdsAndType(shopsIds, type);
        // 组装数据
        List<Sqfw_formSummary_new> results = new ArrayList<>();
        for (SqfwShopsBaseInfo baseInfo : sqfwShopsBaseInfos) {
            Optional<Sqfw_formSummary_new> optional = list.stream().filter(e -> e.getShopsBaseInfoId().equals(baseInfo.getId())).findFirst();
            if (optional.isPresent()) {
                results.add(optional.get());
                continue;
            }
            Sqfw_formSummary_new summaryNew = new Sqfw_formSummary_new();
            summaryNew.setParamData(JSONObject.toJSONString(baseInfo));
            summaryNew.setShopsBaseInfoId(baseInfo.getId()).setShopsBaseInfo(baseInfo)
                    .setFillDate(baseInfo.getFillDate() != null ? DateUtils.toDateByLocalDateTime(baseInfo.getFillDate()) : DateUtil.parse(CommonConstants.WASTE_CREATE_TIME));
            results.add(summaryNew);
        }
        return results;
    }

    @Override
    public Sqfw_formSummary_new getToFlowId(String flowId) {
        Cnd cnd = Cnd.NEW();
        cnd.and("sqfw_flow_id", "=", flowId);
        return super.fetch(cnd);
    }

    @Override
    public List<Sqfw_formSummary_new> queryByCondition(Map<String, Object> param, String type) {
        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getType, "=", type);
        if (ObjectUtils.isNotEmpty(param.get("fillStartDate"))) {
            cnd.and(Sqfw_formSummary_new::getFillDate, ">", String.format("%s 00:00:00", param.get("fillStartDate")));
        }
        if (ObjectUtils.isNotEmpty(param.get("fillEndDate"))) {
            cnd.and(Sqfw_formSummary_new::getFillDate, "<", String.format("%s 23:59:59", param.get("fillEndDate")));
        }
        if (ObjectUtils.isNotEmpty(param.get("shopInfoId"))) {
            cnd.and(Sqfw_formSummary_new::getShopsBaseInfoId, "=", param.get("shopInfoId"));
        }
        Sys_user user = currUserService.getUserById(SecurityUtil.getUserId());
        //拼接五级 省
        cnd.and(Sqfw_formSummary_new::getProvince, "=", user.getProvince());
        //拼接五级 市
        cnd.and(Sqfw_formSummary_new::getCity, "=", user.getCity());
        //拼接五级 区
        cnd.and(Sqfw_formSummary_new::getDistrict, "=", user.getDistrict());
        //拼接五级 街道
        cnd.and(Sqfw_formSummary_new::getCounty, "=", user.getCounty());
        //拼接五级 社区
        cnd.and(Sqfw_formSummary_new::getCommunity, "=", user.getCommunity());
        cnd.getOrderBy().desc(Sqfw_formSummary_new::getFillDate);
        return this.query(cnd);
    }

    @Override
    public List<Sqfw_formSummary_new> queryJinYangGasUse(Map<String, Object> param, String type) {
        Sys_user user = currUserService.getUserById(SecurityUtil.getUserId());
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(" select * from ( ");
        stringBuilder.append(" select *,row_number() over(partition by shops_base_info_id order by fill_date  desc) as num from  shequ.sqfw_form_summary_new ");
        stringBuilder.append(" where type='").append(type).append("'");
        stringBuilder.append(" and  param_data ->>'type'='九小场所'");
        stringBuilder.append(" and province ='").append(user.getProvince()).append("'");
        stringBuilder.append(" and city ='").append(user.getCity()).append("'");
        stringBuilder.append(" and district ='").append(user.getDistrict()).append("'");
        stringBuilder.append(" and county ='").append(user.getCounty()).append("'");
        stringBuilder.append(" and community ='").append(user.getCommunity()).append("'");
        if (ObjectUtils.isNotEmpty(param.get("fillStartDate"))) {
            stringBuilder.append(" and fill_date >'").append(String.format("%s 00:00:00", param.get("fillStartDate"))).append("' and fill_date <'").append(String.format("%s 23:59:59", param.get("fillEndDate"))).append("'");
        }
        if (ObjectUtils.isNotEmpty(param.get("shopInfoId"))) {
            stringBuilder.append(" and shops_base_info_id ='").append(param.get("shopInfoId")).append("'");
        }
        stringBuilder.append(" )a where a.num=1");
        return this.listEntity(Sqls.create(stringBuilder.toString()));
    }

    @Override
    public void batchDeleteFormSummary(List<String> formSummaryIds) {
        if (formSummaryIds == null || formSummaryIds.size() == 0) {
            throw new AppException(ResultCode.NULL_DATA_ERROR.getMsg());
        }
        // 查询数据
        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary::getId, "in", formSummaryIds);
        List<Sqfw_formSummary_new> list = this.query(cnd);
        log.info("batchDeleteFormSummary Sqfw_formSummary_new query res:{}", JSONObject.toJSONString(list));
        if (list.isEmpty()) {
            throw new AppException(ResultCode.NULL_DATA_ERROR.getMsg());
        }
        String userId = SecurityUtil.getUserId();
        // 异步执行删除操作
        CompletableFuture[] cf = list.stream().map(data -> CompletableFuture.runAsync(() ->
                        batchDeleteData(userId, data), taskUpdateExecutor)
                .thenApply(r -> r)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(cf).join();
    }

    private void batchDeleteData(String userId, Sqfw_formSummary_new data) {
        //1 记录日志
        sysLogService.insertDelLog(userId, JSONObject.toJSONString(data), Sqfw_cenSusPaper.class.getAnnotation(Table.class).value(),
                "com.budwk.app.sqfw.services.impl.SqfwFormsummaryNewServiceImpl.batchDeleteFormSummary",
                "com.budwk.app.sqfw.controllers.admin.SqfwFormsummaryNewController.batchDeleteFormSummary");
        // 2 删除数据
        sqfwCompleteflowService.deleteAndUpdateWO(data.getSqfwFlowId());
    }
}
